<?php
/**
* 订单明细--淘分销特殊处理版本,当一个OBJ中有两条相同货号的明细
*
* @category apibusiness
* @package apibusiness/response/order/component/itemstfxv
* @author chenping<chenping@shopex.cn>
* @version $Id: items.php 2013-3-12 17:23Z
*/
class apibusiness_response_order_component_itemstfxv extends apibusiness_response_order_component_abstract
{
    const _APP_NAME = 'ome';

    private $_obj_alias = array(
        'goods'       => '商品',
        'pkg'         => '促销类',
        'gift'        => '赠品',
        'giftpackage' => '礼包',
    );

    /**
     * 订单新增时候的数据格式转换
     *
     * @return void
     * @author 
     **/
    public function convert(){

        $is_fail_order = false;
        $salesMLib = kernel::single('material_sales_material');
        foreach ($this->_platform->_ordersdf['order_objects'] as $object) {
            //obj基础数据格式化
            $quantity = $object['quantity'] ? $object['quantity'] : 1;
            $obj_amount = $object['amount'] ? $object['amount'] : bcmul($quantity, $object['price'],3);
            $obj_sale_price = (isset($object['sale_price']) && is_numeric($object['sale_price']) && -1 != bccomp($object['sale_price'], 0, 3) ) ? $object['sale_price'] :  bcsub($obj_amount,bcadd($object['pmt_price'], $object_pmt,3),3);

            //检查货品是否存在销售物料中
            $salesMInfo = $salesMLib->getSalesMByBn($this->_platform->_ordersdf['shop_id'],$object['bn']);
            if($salesMInfo){
                $basicMInfos = $salesMLib->getBasicMBySalesMId($salesMInfo['sm_id']);
                if($basicMInfos){
                    //如果是促销类销售物料
                    if($salesMInfo['sales_material_type'] == 2){
                        //根据本地具体的类型判定是哪种obj类型
                        $obj_type = 'pkg';

                        //item层关联基础物料平摊销售价
                        $salesMLib->calProSaleMPriceByRate($obj_sale_price, $basicMInfos);
                        
                        //组织item数据
                        foreach($basicMInfos as $k => $basicMInfo){
                            //$basicMInfo['retail_price'] ? $basicMInfo['retail_price'] : 0.00
                            $sendnum = $this->_platform->_ordersdf['ship_status'] == '0' ? 0 : $basicMInfo['number']*$quantity;

                            $order_items[] = array(
                                'shop_goods_id'   => $object['shop_goods_id'] ? $object['shop_goods_id'] : 0,
                                'product_id'      => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0,
                                'shop_product_id' => 0,
                                'bn'              => $basicMInfo['material_bn'],
                                'name'            => $basicMInfo['material_name'],
                                'cost'            => $basicMInfo['cost'] ? $basicMInfo['cost'] : 0.00,
                                'price'           => $basicMInfo['rate_price'] ? bcdiv($basicMInfo['rate_price'], $basicMInfo['number']*$quantity, 2) : 0.00,
                                'pmt_price'       => 0.00,
                                'sale_price'      => $basicMInfo['rate_price'] ? $basicMInfo['rate_price'] : 0.00,
                                'amount'          => $basicMInfo['rate_price'] ? $basicMInfo['rate_price'] : 0.00,
                                'weight'          => $basicMInfo['weight'] ? $basicMInfo['weight'] : 0.00,
                                'quantity'        => $basicMInfo['number']*$quantity,
                                'addon'           => '',
                                'item_type'       => 'pkg',
                                'delete'          => ($object['status'] == 'close') ? 'true' : 'false',
                                'sendnum'         => $sendnum,
                            );
                        }
                    }else{
                        //根据本地具体的类型判定是哪种obj类型 普通、赠品
                        $obj_type = ($salesMInfo['sales_material_type'] == 1) ? 'goods' : 'gift';
                        $item_type = ($obj_type == 'goods') ? 'product' : 'gift';

                        //如果是赠品重置相关的金额字段
                        if($obj_type == 'gift'){
                            $object['cost'] = 0.00;
                            $object['price'] = 0.00;
                            $object['pmt_price'] = 0.00;
                            $object['sale_price'] = 0.00;
                            $object['amount'] =0.00;
                            $obj_amount = 0.00;
                            $obj_sale_price = 0.00;
                        }

                        //普通销售物料
                        foreach($basicMInfos as $k => $basicMInfo){
                            
                            $addon = '';
                            if ($object['product_attr']) {
                                $addon = serialize(array('product_attr'=>$object['product_attr']));
                            }

                            $sendnum = $this->_platform->_ordersdf['ship_status'] == '0' ? 0 : $object['sendnum']*$basicMInfo['number'];

                            //普通销售物料item层数据以object为主,原本就是1:1的两层结构,item合并object,item层数据真实
                            $order_items[] = array(
                                'shop_goods_id'   => $object['shop_goods_id'] ? $object['shop_goods_id'] : 0,
                                'product_id'      => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0,
                                'shop_product_id' => $object['shop_product_id'] ? $object['shop_product_id'] : 0,
                                'bn'              => $basicMInfo['material_bn'],
                                'name'            => $basicMInfo['material_name'],
                                'cost'            => (float)$object['cost'] ? $object['cost'] : $basicMInfo['cost'],
                                'price'           => (float)$object['price'],
                                'pmt_price'       => (float)$object['pmt_price'],
                                'sale_price'      => (isset($object['sale_price']) && is_numeric($object['sale_price']) && -1 != bccomp($object['sale_price'], 0, 3) ) ? $object['sale_price'] : bcsub($obj_amount, (float)$object['pmt_price'],3),
                                'amount'          => $obj_amount,
                                'weight'          => (float)$object['weight'] ? $object['weight'] : ($basicMInfo['weight'] ? $basicMInfo['weight'] : 0.00),
                                'quantity'        => $basicMInfo['number']*$quantity,
                                'addon'           => $addon,
                                'item_type'       => $item_type,
                                'delete'          => ($object['status'] == 'close') ? 'true' : 'false',
                                'sendnum'         => $sendnum,
                            );
                        }
                    }
                }else{
                    $is_fail_order = true;
                }
            }else{
                $is_fail_order = true;
            }

            $this->_platform->_newOrder['order_objects'][] = array(
                'obj_type'      => $obj_type ? $obj_type : 'goods',
                'obj_alias'     => $object['obj_alias'] ? $object['obj_alias'] : $this->_obj_alias[$obj_type],
                'shop_goods_id' => $object['shop_goods_id'] ? $object['shop_goods_id'] : 0,
                'goods_id'      => $salesMInfo['sm_id'] ? $salesMInfo['sm_id'] : 0,
                'bn'            => $object['bn'] ? $object['bn'] : null,
                'name'          => $object['name'],
                'price'         => $object['price'] ? (float)$object['price'] : bcdiv($obj_amount,$object['quantity'],3),
                'amount'        => $obj_amount,
                'quantity'      => $object['quantity'],
                'weight'        => (float)$object['weight'],
                'score'         => (float)$object['score'],
                'pmt_price'     => (float)$object['pmt_price'],
                'sale_price'    => $obj_sale_price,
                'order_items'   => $order_items,
                'is_oversold'   => ($object['is_oversold'] == true) ? 1 : 0,
                'oid'           => $object['oid'],
                //flag可能从item上移到obj层上要保留的数据
                'delete'          => ($object['status'] == 'close') ? 'true' : 'false',
                'original_str'    => $object['original_str'],
                'product_attr'    => $object['product_attr'],
                'promotion_id'   =>$object['promotion_id'],
            );
            unset($order_items);
        }

        if($is_fail_order){
            $this->_platform->_newOrder['is_fail']     = 'true';
            $this->_platform->_newOrder['edit_status'] = 'true';
            $this->_platform->_newOrder['archive']     = '1';
        }
    }

    /**
     * 更新订单明细
     *
     * @return void
     * @author 
     **/
    public function update()
    {
        //如果订单还没发货进行商品明细的比较
        if ($this->_platform->_tgOrder['ship_status'] == '0') {

            //组织天下掉下来的新数据
            $sky_ordersdf_is_fail_order = false;
            $salesMLib = kernel::single('material_sales_material');
            foreach ($this->_platform->_ordersdf['order_objects'] as $object) {
                //检查货品是否存在销售物料中
                $salesMInfo = $salesMLib->getSalesMByBn($this->_platform->_ordersdf['shop_id'],$object['bn']);
                if($salesMInfo){
                    $basicMInfos = $salesMLib->getBasicMBySalesMId($salesMInfo['sm_id']);
                    if($basicMInfos){
                        //obj基础数据格式化
                        $quantity = $object['quantity'] ? $object['quantity'] : 1;
                        $obj_amount = $object['amount'] ? $object['amount'] : bcmul($quantity, $object['price'],3);
                        $obj_sale_price = (isset($object['sale_price']) && is_numeric($object['sale_price']) && -1 != bccomp($object['sale_price'], 0, 3) ) ? $object['sale_price'] :  bcsub($obj_amount,bcadd($object['pmt_price'], $object_pmt,3),3);

                        //如果是促销类销售物料
                        if($salesMInfo['sales_material_type'] == 2){
                            //根据本地具体的类型判定是哪种obj类型
                            $obj_type = 'pkg';

                            //item层关联基础物料平摊销售价
                            $salesMLib->calProSaleMPriceByRate($obj_sale_price, $basicMInfos);
                            
                            //组织item数据
                            foreach($basicMInfos as $k => $basicMInfo){
                                //$basicMInfo['retail_price'] ? $basicMInfo['retail_price'] : 0.00
                                $sendnum = $this->_platform->_ordersdf['ship_status'] == '0' ? 0 : $basicMInfo['number']*$quantity;
                                $item_sale_price = $basicMInfo['rate_price'] ? $basicMInfo['rate_price'] : 0.00;
                                $salepricekey = bcdiv((float) $item_sale_price, $basicMInfo['number']*$quantity,3);
                                $itemkey = sprintf('%u',crc32(trim($basicMInfo['material_bn']) . '-pkg-' .$salepricekey));

                                $order_items[$itemkey] = array(
                                    'shop_goods_id'   => $object['shop_goods_id'] ? $object['shop_goods_id'] : 0,
                                    'product_id'      => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0,
                                    'shop_product_id' => 0,
                                    'bn'              => $basicMInfo['material_bn'],
                                    'name'            => $basicMInfo['material_name'],
                                    'cost'            => $basicMInfo['cost'] ? $basicMInfo['cost'] : 0.00,
                                    'price'           => $item_sale_price ? bcdiv($item_sale_price, $basicMInfo['number']*$quantity, 2) : 0.00,
                                    'pmt_price'       => 0.00,
                                    'sale_price'      => $item_sale_price,
                                    'amount'          => $item_sale_price,
                                    'weight'          => $basicMInfo['weight'] ? $basicMInfo['weight'] : 0.00,
                                    'quantity'        => $basicMInfo['number']*$quantity,
                                    'addon'           => '',
                                    'item_type'       => 'pkg',
                                    'delete'          => ($object['status'] == 'close') ? 'true' : 'false',
                                    'sendnum'         => $sendnum,
                                );
                            }
                        }else{
                            //根据本地具体的类型判定是哪种obj类型 普通、赠品
                            $obj_type = ($salesMInfo['sales_material_type'] == 1) ? 'goods' : 'gift';
                            $item_type = ($obj_type == 'goods') ? 'product' : 'gift';

                            //如果是赠品重置相关的金额字段
                            if($obj_type == 'gift'){
                                $object['cost'] = 0.00;
                                $object['price'] = 0.00;
                                $object['pmt_price'] = 0.00;
                                $object['sale_price'] = 0.00;
                                $object['amount'] =0.00;
                                $obj_amount = 0.00;
                                $obj_sale_price = 0.00;
                            }

                            //普通销售物料
                            foreach($basicMInfos as $k => $basicMInfo){
                                
                                $addon = '';
                                if ($object['product_attr']) {
                                    $addon = serialize(array('product_attr'=>$object['product_attr']));
                                }

                                $sendnum = $this->_platform->_ordersdf['ship_status'] == '0' ? 0 : $object['sendnum']*$basicMInfo['number'];
                                $item_sale_price = (isset($object['sale_price']) && is_numeric($object['sale_price']) && -1 != bccomp($object['sale_price'], 0, 3) ) ? $object['sale_price'] : bcsub($obj_amount, (float)$object['pmt_price'],3);
                                $salepricekey = bcdiv((float) $item_sale_price, $basicMInfo['number']*$quantity,3);
                                $itemkey = sprintf('%u',crc32(trim($basicMInfo['material_bn']) . '-product-' .$salepricekey));

                                //普通销售物料item层数据以object为主,原本就是1:1的两层结构，item合并object,item层数据真实
                                $order_items[$itemkey] = array(
                                    'shop_goods_id'   => $object['shop_goods_id'] ? $object['shop_goods_id'] : 0,
                                    'product_id'      => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0,
                                    'shop_product_id' => $object['shop_product_id'] ? $object['shop_product_id'] : 0,
                                    'bn'              => $basicMInfo['material_bn'],
                                    'name'            => $basicMInfo['material_name'],
                                    'cost'            => (float)$object['cost'] ? $object['cost'] : $basicMInfo['cost'],
                                    'price'           => (float)$object['price'],
                                    'pmt_price'       => (float)$object['pmt_price'],
                                    'sale_price'      => $item_sale_price,
                                    'amount'          => $obj_amount,
                                    'weight'          => (float)$object['weight'],
                                    'quantity'        => $basicMInfo['number']*$quantity,
                                    'addon'           => $addon,
                                    'item_type'       => $item_type,
                                    'delete'          => ($object['status'] == 'close') ? 'true' : 'false',
                                    'sendnum'         => $sendnum,
                                );
                            }
                        }
                    }else{
                        $sky_ordersdf_is_fail_order = true;
                    }
                }else{
                    $sky_ordersdf_is_fail_order = true;
                }

                $obj_type = $obj_type ? $obj_type : 'goods';
                $objkey = sprintf('%u',crc32(trim($object['bn']) . '-' . trim($obj_type) . '-' . trim($object['oid'])));
                $sky_ordersdf['order_objects'][$objkey] = array(
                    'obj_type'      => $obj_type,
                    'obj_alias'     => $object['obj_alias'] ? $object['obj_alias'] : $this->_obj_alias[$obj_type],
                    'shop_goods_id' => $object['shop_goods_id'] ? $object['shop_goods_id'] : 0,
                    'goods_id'      => $salesMInfo['sm_id'] ? $salesMInfo['sm_id'] : 0,
                    'bn'            => $object['bn'] ? $object['bn'] : null,
                    'name'          => $object['name'],
                    'price'         => $object['price'] ? (float)$object['price'] : bcdiv($obj_amount,$object['quantity'],3),
                    'amount'        => $obj_amount,
                    'quantity'      => $object['quantity'],
                    'weight'        => (float)$object['weight'],
                    'score'         => (float)$object['score'],
                    'pmt_price'     => (float)$object['pmt_price'],
                    'sale_price'    => $obj_sale_price,
                    'order_items'   => $order_items,
                    'is_oversold'   => ($object['is_oversold'] == true) ? 1 : 0,
                    'oid'           => $object['oid'],
                    //flag可能从item上移到obj层上要保留的数据
                    'delete'          => ($object['status'] == 'close') ? 'true' : 'false',
                    'original_str'    => $object['original_str'],
                    'product_attr'    => $object['product_attr'],
                    'promotion_id'   =>$object['promotion_id'],
                );
            }

            //先重组下原始订单的明细以货号+类型的
            foreach($this->_platform->_tgOrder['order_objects'] as $k => $tg_object){
                $objkey = sprintf('%u',crc32(trim($tg_object['bn']) . '-' . trim($tg_object['obj_type']) . '-' . trim($tg_object['oid'])));
                $old_ordersdf['order_objects'][$objkey] = $tg_object;
                foreach($tg_object['order_items'] as $ik => $item){
                    $salepricekey = bcdiv((float) $item['sale_price'], $item['quantity'],3);
                    $itemkey = sprintf('%u',crc32(trim($item['bn']) . '-' . trim($item['item_type']) . '-' .$salepricekey));
                    $old_ordersdf['order_objects'][$objkey]['order_items'][$itemkey] = $item;
                }
            }

            $basicMStockLib = kernel::single('material_basic_material_stock');
            $basicMStockFreezeLib = kernel::single('material_basic_material_stock_freeze');

            //先用老数组检查变化,不存在的将明细内容定义为删除状态并释放冻结
            foreach($old_ordersdf['order_objects'] as $objkey => $old_object){
                //如果天上掉下来的没老的object这层了
                if(!isset($sky_ordersdf['order_objects'][$objkey])){
                    foreach ($old_object['order_items'] as $itemkey=>$old_item) {
                        //如果本地已经是删除状态了，跳过
                        if($old_item['delete'] == 'true'){continue;}

                        $this->_platform->_newOrder['order_objects'][$objkey]['obj_id'] = $old_object['obj_id'];
                        $this->_platform->_newOrder['order_objects'][$objkey]['order_items'][$itemkey] = array('item_id'=>$old_item['item_id'],'delete'=>'true');

                        // 扣库存
                        if ($old_item['product_id']) {
                            $basicMStockLib->unfreeze($old_item['product_id'],$old_item['quantity']);
                            $basicMStockFreezeLib->unfreeze($old_item['product_id'], material_basic_material_stock_freeze::__ORDER, $this->_platform->_tgOrder['order_id'], '', material_basic_material_stock_freeze::__SHARE_STORE, $old_item['quantity']);
                        }
                    }
                }
            }

            //用新的数据数组做比较，变化的更新，新增的增加
            foreach ($sky_ordersdf['order_objects'] as $objkey => $object) {
                $obj_id = $old_ordersdf['order_objects'][$objkey]['obj_id'];
                $order_items = $object['order_items']; unset($object['order_items']);

                $object = array_filter($object,array($this,'filter_null'));
                // OBJECT比较
                $diff_obj = array_udiff_assoc((array)$object, (array)$old_ordersdf['order_objects'][$objkey],array($this,'comp_array_value'));
                if ($diff_obj) {
                    $diff_obj['obj_id'] = $obj_id;
                    $this->_platform->_newOrder['order_objects'][$objkey] = array_merge((array)$this->_platform->_newOrder['order_objects'][$objkey],(array)$diff_obj);
                }
                
                if($order_items){
                    foreach ($order_items as $itemkey => $item) {
                        $item = array_filter($item,array($this,'filter_null'));
                        // ITEM比较
                        $item_id = $old_ordersdf['order_objects'][$objkey]['order_items'][$itemkey]['item_id'];
                        $diff_item = array_udiff_assoc((array)$item, (array)$old_ordersdf['order_objects'][$objkey]['order_items'][$itemkey],array($this,'comp_array_value'));

                        if ($diff_item) {
                            $diff_item['item_id'] = $item_id;

                            $this->_platform->_newOrder['order_objects'][$objkey]['order_items'][$itemkey] = array_merge((array)$this->_platform->_newOrder['order_objects'][$objkey]['order_items'][$itemkey],(array)$diff_item);

                            if ($diff_item['delete'] == 'false' && $item['product_id']) {
                                $basicMStockLib->freeze($item['product_id'], $item['quantity']);
                                $basicMStockFreezeLib->freeze($item['product_id'], material_basic_material_stock_freeze::__ORDER, $this->_platform->_tgOrder['order_id'], $this->_platform->_ordersdf['shop_id'], 0, material_basic_material_stock_freeze::__SHARE_STORE, $item['quantity']);
                            } elseif ($diff_item['delete'] == 'true' && $item['product_id']) {
                                $basicMStockLib->unfreeze($item['product_id'], $old_ordersdf['order_objects'][$objkey]['order_items'][$itemkey]['quantity']);
                                $basicMStockFreezeLib->unfreeze($item['product_id'], material_basic_material_stock_freeze::__ORDER, $this->_platform->_tgOrder['order_id'], '', material_basic_material_stock_freeze::__SHARE_STORE, $old_ordersdf['order_objects'][$objkey]['order_items'][$itemkey]['quantity']);
                            } elseif (isset($diff_item['quantity']) && $item['product_id']) {
                                // 如果库存发生变化，
                                $diff_quantity = bcsub($diff_item['quantity'], $old_ordersdf['order_objects'][$objkey]['order_items'][$itemkey]['quantity']);
                                if($diff_quantity > 0){
                                    $basicMStockLib->freeze($item['product_id'], abs($diff_quantity));
                                    $basicMStockFreezeLib->freeze($item['product_id'], material_basic_material_stock_freeze::__ORDER, $this->_platform->_tgOrder['order_id'], $this->_platform->_ordersdf['shop_id'], 0, material_basic_material_stock_freeze::__SHARE_STORE, abs($diff_quantity));
                                }elseif($diff_quantity < 0){
                                    $basicMStockLib->unfreeze($item['product_id'], abs($diff_quantity));
                                    $basicMStockFreezeLib->unfreeze($item['product_id'], material_basic_material_stock_freeze::__ORDER, $this->_platform->_tgOrder['order_id'], '', material_basic_material_stock_freeze::__SHARE_STORE, abs($diff_quantity));
                                }
                            }
                        
                            $this->_platform->_newOrder['order_objects'][$objkey]['obj_id'] = $obj_id;
                        }
                    }
                }
            }

            if (!$sky_ordersdf_is_fail_order && $this->_platform->_tgOrder['is_fail'] == 'true') {
                $this->_platform->_newOrder['is_fail']     = 'false';
                $this->_platform->_newOrder['edit_status'] = 'false';
                $this->_platform->_newOrder['archive']     = '0';
            }elseif($sky_ordersdf_is_fail_order){
                $this->_platform->_newOrder['is_fail']     = 'true';
                $this->_platform->_newOrder['edit_status'] = 'true';
                $this->_platform->_newOrder['archive']     = '1';
            }

            // 日志
            if ($this->_platform->_newOrder['order_objects']) {
                //后期修改 分销订单的处理
                $logModel = app::get(self::_APP_NAME)->model('operation_log');
                $logModel->write_log('order_edit@ome',$this->_platform->_tgOrder['order_id'],'订单商品信息被修改');
            }
        }
    }
}